package com.pxmeta.circle.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.pxmeta.circle.entity.Circle;
import com.pxmeta.circle.entity.UserCircle;
import com.pxmeta.circle.entity.dto.UpdateCircleDTO;
import com.pxmeta.circle.entity.vo.ParentCircleVO;
import com.pxmeta.circle.enums.PrivacyTypeEnum;
import com.pxmeta.circle.mapper.KtCircleMapper;
import com.pxmeta.circle.service.ICirclePrivilegeService;
import com.pxmeta.circle.service.ICircleService;
import com.pxmeta.circle.service.IUserCircleService;
import com.pxmeta.common.constant.HttpStatus;
import com.pxmeta.common.constant.Status;
import com.pxmeta.common.core.domain.AjaxResult;
import com.pxmeta.common.enums.CircleUserLevelEnum;
import com.pxmeta.common.exception.ServiceException;
import com.pxmeta.common.utils.StringUtils;
import com.pxmeta.dynamic.service.IMailService;
import com.pxmeta.user.entity.User;
import com.pxmeta.user.mapper.UserMapper;
import com.pxmeta.verify.entity.UserReal;
import com.pxmeta.verify.service.IUserRealService;
import com.pxmeta.verify.service.VerifyService;
import org.apache.commons.compress.utils.Lists;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 圈子Service业务层处理
 *
 * @author wcl
 * @date 2022-04-17
 */
@Service
@SuppressWarnings("all")
public class CircleServiceImpl extends ServiceImpl<KtCircleMapper, Circle> implements ICircleService {

    @Autowired
    private KtCircleMapper ktCircleMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private IUserRealService userRealService;

    @Autowired
    private VerifyService verifyService;

    @Autowired
    @Lazy
    private IUserCircleService userCircleService;

    @Autowired
    private ICirclePrivilegeService circlePrivilegeService;

    @Autowired
    private IMailService mailService;


    /**
     * 获取用户圈子列表
     * @param userId
     * @return
     */
    @Override
    public List<Circle> getUserCircle(Long userId) {
        List<Circle> userCircle = userCircleService.getUserCircle(userId);
        if(CollectionUtil.isEmpty(userCircle)){
            return Lists.newArrayList();
        }
        patchData(userCircle);
        return userCircle;
    }


    @Override
    public List<Circle> getCircleList(Long userId, Integer type, Integer page, Integer size,String name) {

////        List<Long> circleIds = getUserCircle(userId).stream().map(Circle::getId).collect(Collectors.toList());
//        LambdaQueryWrapper<Circle> wrapper = Wrappers.lambdaQuery();
//        //过滤私密圈子 和 默认圈子
//        wrapper.eq(Circle::getStatus,Status.SUCCESS.getValue())
//                .ne(Circle::getId,1)
//                .eq(Circle::getPrivacyType, PrivacyTypeEnum.PUBLIC.getType());
////        if (CollectionUtil.isNotEmpty(circleIds)){
////            wrapper.notIn(Circle::getId, circleIds);
////        }
//
//        if (StringUtils.isNotEmpty(name)){
//            wrapper.like(Circle::getName, name);
//        }else if (type == 0){//推荐
//            wrapper.orderByDesc(Circle::getHot);
//        }else {
//            wrapper.eq(Circle::getType, type)
//                    .orderByDesc(Circle::getCreateTime);
//        }
//        List<Circle> list = this.page(new Page<>(page, size), wrapper).getRecords();
//        patchData(list);

        return new ArrayList<>();
    }

    private void patchData(List<Circle> list){
        List<Long> circleIds = list.stream().map(Circle::getId).collect(Collectors.toList());
        LambdaQueryWrapper<UserCircle> userCircleWrapper = Wrappers.lambdaQuery();
        if (circleIds.isEmpty()){
            return;
        }
        userCircleWrapper.in(UserCircle::getCircleId, circleIds)
                .ne(UserCircle::getLevel,0);
        List<UserCircle> userCircles = userCircleService.list(userCircleWrapper);
        List<Long> userIds = userCircles.stream().map(UserCircle::getUserId).collect(Collectors.toList());
        List<User> users = Lists.newArrayList();
        if (!userIds.isEmpty()){
            users = userMapper.selectBatchIds(userIds);
        }
        Map<Long, List<UserCircle>> map = userCircles.stream().collect(Collectors.groupingBy(UserCircle::getCircleId));
        HashMap<Long,List<User>> circleUserMap = Maps.newHashMap();
        for (Map.Entry<Long, List<UserCircle>> userCircleMap : map.entrySet()) {
            Long key = userCircleMap.getKey();
            List<Long> circleUserIds = userCircleMap.getValue().stream().map(UserCircle::getUserId).collect(Collectors.toList());
            List<User> adminUsers = users.stream().filter(user -> {
                return circleUserIds.contains(user.getId());
            }).collect(Collectors.toList());
            circleUserMap.put(key,adminUsers);
        }
        if (CollectionUtil.isNotEmpty(userCircles)) {
            for (Circle circle : list) {
                List<User> adminUsers = circleUserMap.get(circle.getId());
                if (null == adminUsers){
                    adminUsers = new ArrayList<>();
                }
                circle.setAdminUsers(adminUsers);
                if (circle.getIsSystem() == 1){
                    ParentCircleVO parentVO = new ParentCircleVO();
                    parentVO.setCircleId(circle.getId());
                    parentVO.setName(circle.getName());
                    circle.setParentCircle(parentVO);
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void create(Circle circle, Long userId) {
        circle.setUserCount(1L);
        this.save(circle);
        User user = userMapper.selectById(userId);
        UserCircle userCircle = new UserCircle();
        Long circleId = circle.getId();
        userCircle.setCircleId(circleId);
        userCircle.setUserId(userId);
        userCircle.setSort(0);
        userCircle.setNickname(user.getNickname());
        userCircle.setLevel(CircleUserLevelEnum.CREATOR.getLevel());
        //审核
        List<String> textList = new LinkedList<>();
        textList.add(circle.getDescription());
        textList.add(circle.getName());
        List<String> imgList = new LinkedList<>();
        imgList.add(circle.getAvatar());
        imgList.add(circle.getBgUrl());
        Status status = verifyService.audit(textList, imgList);

        if (status != Status.SUCCESS){
            throw new ServiceException("内容违规,无法创建!");
        }
        circle.setStatus(status.getValue());

        userCircleService.save(userCircle);
        circlePrivilegeService.initCirclePrivilege(circleId);
    }

    @Override
    public Circle getSystemCircle() {
        LambdaQueryWrapper<Circle> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Circle::getType, 0);
        return this.getOne(wrapper);
    }

    @Override
    public Circle getDetail(Long circleId) {
        Circle circle = this.getById(circleId);
        List<User> adminUsers = userCircleService.getAdminUserByCircleId(circleId);
        circle.setAdminUsers(adminUsers);
        if (circle.getIsSystem() == 1){
            ParentCircleVO parentVO = new ParentCircleVO();
            parentVO.setCircleId(circle.getId());
            parentVO.setName(circle.getName());
            circle.setParentCircle(parentVO);
        }
        return circle;
    }

    @Override
    public List<Circle> getSysCircleList(Integer type) {
        LambdaQueryWrapper<Circle> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Circle::getType, type)
                .eq(Circle::getIsSystem, 1);
        return this.list(wrapper);
    }

    @Override
    public void updateCircle(UpdateCircleDTO dto, Long userId) {
        LambdaQueryWrapper<UserCircle> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(UserCircle::getCircleId, dto.getId())
                .eq(UserCircle::getUserId, userId);
        UserCircle uc = userCircleService.getOne(wrapper);
        if (null == uc) {
            throw new ServiceException("没有加入该圈子！",HttpStatus.PARAMS_ERROR);
        }
        Long circleId = uc.getCircleId();
        Circle circle = this.getById(circleId);
        BeanUtils.copyProperties(dto, circle);
        //审核
        List<String> textList = new LinkedList<>();
        textList.add(circle.getDescription());
        textList.add(circle.getName());
        List<String> imgList = new LinkedList<>();
        imgList.add(circle.getAvatar());
        imgList.add(circle.getBgUrl());
        Status status = verifyService.audit(textList, imgList);
        circle.setStatus(status.getValue());
        this.updateById(circle);
    }

    @Override
    public IPage<Circle> getList(Integer page, Integer size, Integer type, String keyword) {
        LambdaQueryWrapper<Circle> wrapper = Wrappers.lambdaQuery();
        if (StringUtils.isNotEmpty(keyword)){
            wrapper.like(Circle::getName, keyword);
        }
        if (type != 0){//全部
            wrapper.eq(Circle::getType, type);
        }
        wrapper.orderByDesc(Circle::getHot,Circle::getCreateTime);
        Page<Circle> result = this.page(new Page<>(page, size), wrapper);
        List<Circle> list = result.getRecords();
        patchData(list);
        return result;
    }

    @Override
    public Circle getBySchoolName(String schoolName) {
        LambdaQueryWrapper<Circle> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Circle::getName, schoolName)
                .eq(Circle::getIsSystem,1)
                .eq(Circle::getType, 1);
        Circle circle = this.getOne(wrapper);
        if (circle == null){
            throw new ServiceException("该学校圈子不存在！");
        }
        return circle;
    }

    @Override
    public void handleVerifyStudentSuccess(Long userId) {
        List<Circle> schoolCircleList = userCircleService.getUserCircle(userId).stream().filter(uc -> uc.getIsSystem() == 1 && uc.getType() == 1).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(schoolCircleList)){
            return;
        }
        User user = userMapper.selectById(userId);
        UserReal userReal = userRealService.getById(userId);
        String schoolName = user.getSchoolName();
        boolean containsSchool = schoolCircleList.stream().map(Circle::getName).collect(Collectors.toList()).contains(schoolName);
        //如果不存在自动加入当前学校
        if (!containsSchool){
            Circle circle = this.getBySchoolName(schoolName);
            UserCircle userCircle = new UserCircle();
            userCircle.setCircleId(circle.getId());
            userCircle.setUserId(userId);
            userCircle.setNickname(userReal.getRealName());
            userCircle.setSort(0);
            userCircleService.joinCircle(userCircle,false);
        }

        //退出不属于自己的圈子
        for (Circle circle : schoolCircleList) {
            if (!circle.getName().equals(schoolName)){
                userCircleService.quit(userId, circle.getId());
            }
        }

    }
}
